<?php

namespace App\Http\Controllers\Quiz\Paper;

use App\Contracts\Repositories\Quiz\PaperRepository as PaperRepositoryContract;
use App\Contracts\Repositories\Quiz\SheetRepository as SheetRepositoryContract;
use App\Contracts\Repositories\QuizRepository as QuizRepositoryContract;
use App\Entities\Quiz;
use App\Morefun\Profile\AppUserCollector;
use App\Morefun\Quiz\PaperService;
use App\Morefun\Quiz\SheetService;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;

class ApiController
{
    protected $papers;
    protected $paper;
    protected $sheets;
    protected $sheet;
    protected $quizzes;

    public function __construct(
        PaperRepositoryContract $papers,
        SheetRepositoryContract $sheets,
        PaperService $paper,
        SheetService $sheet,
        QuizRepositoryContract $quizzes
    ) {
        $this->papers = $papers;
        $this->sheets = $sheets;
        $this->paper = $paper;
        $this->sheet = $sheet;
        $this->quizzes = $quizzes;
    }

    public function many(Request $request, $id)
    {
        $perPage = $request->get('per_page', 15);

        $papers = $this->papers->findWithPaginate(
            $perPage,
            [['activity_id', '=', $id]],
            ['id', 'user_agent', 'created_at', 'start_at']
        );

        foreach ($papers as $paper) {
            $duration = strtotime($paper->start_at) - strtotime($paper->created_at);
            $paper->durations = abs($duration);
        }

        return response()->success($papers);
    }

    public function sheets($id)
    {
        $paper = $this->papers->find($id, ['activity_id']);

        if (null === $paper) {
            return response()->failed('没有找到资源');
        }

        $sheets = $this->sheets->findAll(
            [['paper_id', '=', $id]],
            ['quiz_id', 'option_id', 'fill_content']
        )->toArray();
        $optionIds = [];
        $contents = [];

        foreach ($sheets as $item) {
            $optionIds = array_merge($optionIds, $item['option_id']);
            $contents[$item['quiz_id']][] = $item['fill_content'];
        }

        $optionIds = array_unique($optionIds);

        $quizzes = $this->quizzes->findAllWithOptions($paper->activity_id, ['id', 'type', 'title']);
        $types = $this->quizzes->types();
        $answer = [];

        foreach ($quizzes as $of => $quiz) {
            $texts = [];
            $answer[$of]['title'] = sprintf('%s [%s]', $quiz->title, $types[$quiz->type]);

            $opts = is_null($quiz->options) ? [] : $quiz->options;
            if ($quiz->type == Quiz::TYPE_FILL_BLANK) {
                if (isset($contents[$quiz->id])) {
                    $texts[] = $contents[$quiz->id];
                }
            }
            foreach ($opts as $i => $opt) {
                if (in_array($opt->id, $optionIds, false)) {
                    $texts[] = $opt->text;
                }
                if (isset($contents[$quiz->id][$i])) {
                    $texts[] = $contents[$quiz->id][$i];
                }
            }

            $answer[$of]['answer'] = implode(' | ', array_filter(Arr::flatten($texts)));
        }


        return response()->success($answer);
    }

    public function write(Request $request)
    {
        $input = $request->json()->all();

        $validator = Validator::make($input, [
            'activity_id' => 'required|uuid',
            'uid' => 'required|max:255',
            'start_time' => 'required|date',
            'sheets' => 'required|array',
        ]);

        if ($validator->fails()) {
            return response()->failed(
                Arr::first($validator->errors()->all()),
                10000
            );
        }
        $flag = $this->checkSignToken($request);
        if(!$flag){
            return response()->failed('验签失败');
        }

        $success = DB::transaction(function () use ($request) {
            $paper = $this->paper->format($request);

            $id = $this->papers->create($paper);

            if (!$id) {
                return false;
            }

            $sheets = $this->sheet->formatSheets($id, $request);

            return $this->sheets->batchCreate($sheets);
        });

        if ($success) {
            app(AppUserCollector::class)->gatherFromHttpReferer($request);
            return response()->success();
        }

        return response()->failed('存储失败');
    }

    public function destroy($id)
    {
        $success = DB::transaction(function () use ($id) {
            if ($this->papers->delete($id)) {
                return $this->sheets->deleteBy('paper_id', $id);
            }

            return false;
        });

        if ($success) {
            return response()->success();
        }

        return response()->failed();
    }

    public function checkSignToken(Request $request){
        $activity_id = $request->json('activity_id');
        $uid = $request->json('uid', '');
        $vote_token = $request->json('vote_token', '');

        if(!$vote_token) {
            $referer = $request->headers->get('referer');
            $query = parse_url($referer, PHP_URL_QUERY);
            if (!$query) {
                return;
            }
            $args = [];
            parse_str($query, $args);
            $vote_token = Arr::get($args, 'uid');
        }

        $cached_vote_token = app('redis')->hget('app:uid:'.$activity_id, $uid);

        return $vote_token == $cached_vote_token;

    }
}
